package com.everwin.web.utils;

import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class DataToDocTemplate {

    private static final Logger log = LoggerFactory.getLogger(DataToDocTemplate.class);


    public static InputStream reportDoc(Map reportData, Map listData, InputStream templateFileInputStream) {

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        IXDocReport report = null;
        ByteArrayInputStream swapStream = null;
        try {
            report = XDocReportRegistry.getRegistry().loadReport(templateFileInputStream, TemplateEngineKind.Freemarker);
            IContext context = report.createContext();
            //单个字段填充
            if (reportData != null) {
                replaceSingleDateTemplate(context, reportData);
            }
            //列表数据字段填充
            if (listData !=null){
                FieldsMetadata metadata=report.createFieldsMetadata();
                loadMetadata(metadata,listData);
                replaceListDataTemplate(context,listData);
            }
            report.process(context, outputStream);
            byte[] xls = outputStream.toByteArray();
            swapStream = new ByteArrayInputStream(xls);
        } catch (IOException e) {
            log.error("文件流获取失败", e);
        } catch (XDocReportException e) {
            log.error("导出失败", e);
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.flush();
                    outputStream.close();
                }
                if (templateFileInputStream != null) {
                    templateFileInputStream.close();
                }
            } catch (IOException e) {
                log.warn("文件流关闭失败", e);
            }
        }
        return swapStream;
    }

    /**
     * DOCX
     * metadata取得类class
     *
     * @param metadata
     * @param mutilMap
     */
    public static void loadMetadata(FieldsMetadata metadata, Map mutilMap) throws XDocReportException {
        if (mutilMap != null) {
            Set set = mutilMap.entrySet();
            for (Iterator it = set.iterator(); it.hasNext(); ) {
                Map.Entry entry = (Map.Entry) it.next();
                metadata.load(entry.getKey().toString(), ((List) entry.getValue()).get(0).getClass(), true);
            }
        }
    }

    /**
     * DOCX
     * 针对单个文本占位符的数据自动填充
     *
     * @param context
     * @param singleMap
     */
    public static void replaceSingleDateTemplate(IContext context, Map singleMap) {
        if (singleMap != null) {
            Set set = singleMap.entrySet();
            for (Iterator it = set.iterator(); it.hasNext(); ) {
                Map.Entry entry = (Map.Entry) it.next();
                //StringUtils.strToRtf 专为解决中文编码在rtf模版中乱码问题。
                context.put(entry.getKey().toString(), entry.getValue() != null ? entry.getValue().toString() : "");
            }
        }
    }

    /**
     * DOCX
     * 针对List的数据自动填充
     *
     * @param context
     * @param map
     * @throws Exception
     */
    public static void replaceListDataTemplate(IContext context, Map map) {
        if (map != null) {
            Set set = map.entrySet();
            for (Iterator it = set.iterator(); it.hasNext(); ) {
                Map.Entry entry = (Map.Entry) it.next();
                context.put(entry.getKey().toString(), entry.getValue());
            }
        }
    }

}
